package com.aizuda.boot.modules.business.performancePlan.service.impl;

import com.aizuda.boot.modules.common.constant.enums.CurrencyEnum;
import com.aizuda.boot.modules.business.performancePlan.dto.CreatePaymentPlanDTO;
import com.aizuda.boot.modules.business.performancePlan.dto.PaymentPlanDetailDTO;
import com.aizuda.boot.modules.business.performancePlan.dto.PaymentPlanGroupDTO;
import com.aizuda.boot.modules.business.performancePlan.dto.PaymentPlanGroupResponseDTO;
import com.aizuda.boot.modules.business.performancePlan.dto.PaymentPlanItemDTO;
import com.aizuda.boot.modules.business.performancePlan.entity.PaymentPlanEntity;
import com.aizuda.boot.modules.business.performancePlan.mapper.PaymentPlanMapper;
import com.aizuda.boot.modules.business.performancePlan.service.PaymentPlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 付款计划 Service 实现类
 */
@Slf4j
@Service
public class PaymentPlanServiceImpl extends ServiceImpl<PaymentPlanMapper, PaymentPlanEntity> implements PaymentPlanService {

    @Override
    public List<PaymentPlanEntity> getByContractId(Integer contractId) {
        return baseMapper.selectByContractId(contractId);
    }

    @Override
    public boolean deleteByContractId(Integer contractId) {
        int deletedCount = baseMapper.deleteByContractId(contractId);
        log.info("删除合同ID为{}的付款计划，删除数量: {}", contractId, deletedCount);
        return deletedCount >= 0;
    }

    @Override
    public List<PaymentPlanEntity> getByPlanGroupId(Integer planGroupId) {
        return baseMapper.selectByPlanGroupId(planGroupId);
    }

    @Override
    public boolean updatePaymentPlan(PaymentPlanEntity paymentPlan) {
        paymentPlan.setUpdateTime(LocalDateTime.now());
        return updateById(paymentPlan);
    }

    /**
     * 创建付款计划
     *
     * @param createPaymentPlanDTO 创建付款计划请求
     * @return 是否创建成功
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean createPaymentPlan(CreatePaymentPlanDTO createPaymentPlanDTO) {
        Integer contractId = createPaymentPlanDTO.getContractId();
        
        // 1. 删除当前合同ID的所有付款计划记录
        deleteByContractId(contractId);
        log.info("已删除合同ID为{}的所有付款计划记录", contractId);

        // 2. 生成新的付款计划记录
        List<PaymentPlanEntity> paymentPlanEntities = new ArrayList<>();
        AtomicInteger planGroupIdGenerator = new AtomicInteger(1);

        for (PaymentPlanGroupDTO groupDTO : createPaymentPlanDTO.getPaymentPlanGroups()) {
            // 为每个组生成自增的计划组ID（从1开始）
            Integer planGroupId = planGroupIdGenerator.getAndIncrement();
            
            // 为组内每个子项创建付款计划记录
            for (PaymentPlanItemDTO itemDTO : groupDTO.getChildren()) {
                PaymentPlanEntity entity = new PaymentPlanEntity();
                
                // 设置基本信息
                entity.setContractId(contractId);
                entity.setPlanGroupId(planGroupId);
                
                // 设置组级别信息（每个子项都要填充）
                entity.setIsCyclePlan(groupDTO.getIsCyclePlan());
                entity.setTotalPeriods(groupDTO.getTotalPeriods());
                entity.setFirstPaymentDate(groupDTO.getFirstPaymentDate());
                entity.setPaymentFrequency(groupDTO.getPaymentFrequency());
                entity.setCycleType(groupDTO.getCycleType());
                
                // 设置子项信息
                entity.setSort(itemDTO.getSort());
                entity.setFulfillmentType(itemDTO.getFulfillmentType());
                entity.setFulfillmentItem(itemDTO.getFulfillmentItem());
                entity.setNeedInvoice(itemDTO.getNeedInvoice());
                entity.setPaymentTimeType(itemDTO.getPaymentTimeType());
                entity.setPaymentDate(itemDTO.getPaymentDate());
                entity.setPaymentInterval(itemDTO.getPaymentInterval());
                entity.setPaymentIntervalType(itemDTO.getPaymentIntervalType());
                entity.setPaymentAmount(itemDTO.getPaymentAmount());
                entity.setCurrencyType(itemDTO.getCurrencyType());
                entity.setPartnerId(itemDTO.getPartnerId());
                entity.setPaymentReceiver(itemDTO.getPaymentReceiverName());
                entity.setPaymentReceiverInfo(itemDTO.getPaymentReceiverInfo());
                entity.setBankAccount(itemDTO.getBankAccount());
                entity.setBankName(itemDTO.getBankName());
                entity.setAccountName(itemDTO.getAccountName());
                entity.setPaymentNote(itemDTO.getPaymentNote());
                
                // 设置时间戳
                LocalDateTime now = LocalDateTime.now();
                entity.setCreateTime(now);
                entity.setUpdateTime(now);
                
                paymentPlanEntities.add(entity);
            }
        }

        // 3. 批量保存付款计划
        boolean result = saveBatch(paymentPlanEntities);
        log.info("批量保存付款计划完成，合同ID: {}, 保存数量: {}, 结果: {}", 
                contractId, paymentPlanEntities.size(), result);
        
        return result;
    }



    @Override
    public List<PaymentPlanGroupResponseDTO> getPaymentPlanDetail(Integer contractId) {
        log.info("获取付款计划详情，合同ID: {}", contractId);

        // 1. 查询所有付款计划
        List<PaymentPlanEntity> paymentPlans = getByContractId(contractId);

        if (paymentPlans.isEmpty()) {
            log.info("未找到付款计划，合同ID: {}", contractId);
            return new ArrayList<>();
        }

        // 2. 按计划组ID分组
        Map<Integer, List<PaymentPlanEntity>> groupedPlans = paymentPlans.stream()
                .collect(Collectors.groupingBy(PaymentPlanEntity::getPlanGroupId));

        // 3. 转换为响应DTO
        List<PaymentPlanGroupResponseDTO> result = groupedPlans.entrySet().stream()
                .map(entry -> {
                    Integer planGroupId = entry.getKey();
                    List<PaymentPlanEntity> plans = entry.getValue();

                    // 获取组级别信息（从第一个计划中获取）
                    PaymentPlanEntity firstPlan = plans.get(0);

                    PaymentPlanGroupResponseDTO groupDTO = new PaymentPlanGroupResponseDTO();
                    groupDTO.setPlanGroupId(planGroupId);
                    groupDTO.setIsCyclePlan(firstPlan.getIsCyclePlan());
                    groupDTO.setPaymentFrequency(firstPlan.getPaymentFrequency());
                    groupDTO.setCycleType(firstPlan.getCycleType());
                    if (firstPlan.getCycleType() != null) {
                        groupDTO.setCycleTypeDesc(firstPlan.getCycleType().getDescription());
                    }
                    groupDTO.setFirstPaymentDate(firstPlan.getFirstPaymentDate());
                    groupDTO.setTotalPeriods(firstPlan.getTotalPeriods());

                    // 转换子项
                    List<PaymentPlanDetailDTO> children = plans.stream()
                            .map(this::convertToDetailDTO)
                            .sorted((a, b) -> Integer.compare(a.getSort(), b.getSort()))
                            .collect(Collectors.toList());

                    groupDTO.setChildren(children);
                    return groupDTO;
                })
                .sorted((a, b) -> Integer.compare(a.getPlanGroupId(), b.getPlanGroupId()))
                .collect(Collectors.toList());

        log.info("获取付款计划详情成功，合同ID: {}, 计划组数量: {}, 总计划数量: {}",
                contractId, result.size(), paymentPlans.size());
        return result;
    }

    /**
     * 转换为详情DTO，包含枚举描述
     */
    private PaymentPlanDetailDTO convertToDetailDTO(PaymentPlanEntity entity) {
        PaymentPlanDetailDTO dto = new PaymentPlanDetailDTO();
        BeanUtils.copyProperties(entity, dto);

        // 设置付款时间类型描述
        if (entity.getPaymentTimeType() != null) {
            dto.setPaymentTimeTypeDesc(entity.getPaymentTimeType().getDescription());
        }

        // 设置付款时间间隔类型描述
        if (entity.getPaymentIntervalType() != null) {
            dto.setPaymentIntervalTypeDesc(entity.getPaymentIntervalType().getDescription());
        }

        // 设置货币类型描述
        if (entity.getCurrencyType() != null) {
            try {
                CurrencyEnum currencyEnum = CurrencyEnum.valueOf(entity.getCurrencyType());
                dto.setCurrencyTypeDesc(currencyEnum.getName());
            } catch (IllegalArgumentException e) {
                // 如果枚举中没有找到对应的货币类型，使用原值
                dto.setCurrencyTypeDesc(entity.getCurrencyType());
                log.warn("未找到货币类型枚举: {}", entity.getCurrencyType());
            }
        }

        return dto;
    }
}
